package com.yfbao.horizon.demo;

import com.alibaba.fastjson.JSONArray;
import com.yfbao.horizon.annotation.TRXRetry;
import com.yfbao.horizon.common.LocalSerializationUtils;
import com.alibaba.fastjson.JSON;
import com.yfbao.horizon.model.TestUser;
import com.yfbao.horizon.service.ClassUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 序列化验证
 * 多线程序列化会占用过多内存，该 FSTConfiguration 对象会内存threadlocal对象，不清理，造成内存占用增高
 */
public class FstTestDemo {


    private static ExecutorService executorService = Executors.newFixedThreadPool(10);

    public static void main(String[] args) {
//        FSTtest();
//        System.out.println(FstTestDemo.class.getName());
        paramsParse();
    }

    private static void FSTtest() {
        String value = factory(20 * 1024 * 1024L);
        System.out.println(value);
        byte[] serialize = LocalSerializationUtils.serialize(value);
        CountDownLatch countDownLatch = new CountDownLatch(50);
        AtomicInteger atomicInteger = new AtomicInteger(0);
        for(int i=0;i<50;i++){
//            Object unserialize = LocalSerializationUtils.unserialize(serialize);
//            countDownLatch.countDown();
            executorService.submit(()->{
//                Object unserialize = LocalSerializationUtils.unserialize(serialize);
//                Object unserialize = LocalSerializationUtils.unserializeAndClear(serialize);
                countDownLatch.countDown();
                System.out.println("finished num:"+ atomicInteger.getAndIncrement());
            });
            System.out.println("num:"+i);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        executorService.shutdownNow();
        System.out.println("finished task");
    }

    private static String factory(Long length){
        StringBuilder builder =new StringBuilder();
        while (true){
            builder.append("azzasdasdasdasdasdq1weqwedasdcsdasdasdqwqaxadasdasdasdasda");
            if(builder.length()>=length){
                break;
            }
        }
        return builder.toString();
    }

    @TRXRetry
    public static void testMethoda(Integer i,String name,TestUser user,List<String> list){
        System.out.println(i);
        System.out.println(name);
        System.out.println(user);
        System.out.println(list);
    }

    private static void paramsParse(){
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbbb");
        TestUser testUser = new TestUser();
        testUser.setName("asdasd");
        String abc = parseToString(11, "abc", testUser, list);
        System.out.println(abc);

//        Method testMethod = ClassUtil.getMethod(new FstTestDemo(), "testMethoda");
        Method testMethod = getMethodByAnntion(new FstTestDemo(), "testMethoda");
        if(testMethod ==null){
            System.out.println("method is null");
            return;
        }
        List<String> paramsList = JSONArray.parseArray(abc, String.class);
        Class<?>[] parameterTypes = testMethod.getParameterTypes();
        if(paramsList.size() != parameterTypes.length){
            System.out.println("参数个数不一致");
            return;
        }

        Object[] objects = new Object[parameterTypes.length];
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> parameterType = parameterTypes[i];
            String s = paramsList.get(i);
            Object o = JSON.parseObject(s, parameterType);
            objects[i]=o;
        }
        try {
            testMethod.invoke(FstTestDemo.class,objects);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


    }


    public static  Method getMethodByAnntion(Object obj,String methodName) {
        Method[] methods = obj.getClass().getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            if(method.getName().equals(methodName)){
                Annotation[] annotations = method.getAnnotations();

                System.out.println(annotations.length);
                TRXRetry annotation = method.getAnnotation(TRXRetry.class);
                if(annotation != null){
                    return  method;
                }
//                for (Class<?> parameterType : parameterTypes) {
//                    return  method
//                }
            }
        }
        return null;
    }



    private static String parseToString(Object... args){
        if(args ==null){
            return "";
        }
        List<String> list = new ArrayList<>(args.length);
        for (Object arg : args) {
            String s = JSON.toJSONString(arg);
            list.add(s);
        }
        return JSON.toJSONString(list);
    }

}
